package com.ants.boot.system.service.impl;

import com.ants.boot.core.Response;
import com.ants.boot.core.enums.DataStatusEnum;
import com.ants.boot.model.BaseModel;
import com.ants.boot.system.dao.SysRoleMapper;
import com.ants.boot.system.domain.SysRole;
import com.ants.boot.system.domain.SysRoleMenu;
import com.ants.boot.system.dto.sysrole.AddRoleDto;
import com.ants.boot.system.dto.sysrole.QueryRoleDto;
import com.ants.boot.system.dto.sysrole.UpdateRoleDto;
import com.ants.boot.system.service.SysRoleMenuService;
import com.ants.boot.system.service.SysRoleService;
import com.ants.boot.system.vo.sysrole.SelectRoleVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 蚂蚁会花呗
 * @date 2022/2/15 15:44
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Override
    public List<String> findByUserId(Integer userId) {
        return sysRoleMapper.findByUserId(userId);
    }

    @Override
    public IPage<SysRole> pageInfo(QueryRoleDto dto) {
        Page<SysRole> page = new Page<>(dto.getPageNum(),dto.getPageSize());
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getName())){
            queryWrapper.lambda()
                    .like(SysRole::getName,dto.getName());
        }
        if (StringUtils.isNotBlank(dto.getStatus())){
            queryWrapper.and(wrapper ->wrapper.lambda().eq(SysRole::getStatus,dto.getStatus()));
        }
        if (StringUtils.isNotBlank(dto.getCreateTime())){
            queryWrapper.and(wrapper ->wrapper.lambda().ge(SysRole::getCreateTime,dto.getCreateTime()));
        }

        return this.page(page,queryWrapper);
    }

    @Override
    @Transactional
    public Response updateRole(UpdateRoleDto dto) {
        Response result = Response.fail();
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .ne(SysRole::getId,dto.getId())
                .and(wrapper ->wrapper.eq(SysRole::getName,dto.getName()).or().eq(SysRole::getRoleName,dto.getRoleName()));
        List<SysRole> list = this.list(queryWrapper);
        if (!list.isEmpty()){
            result.setMsg("名称或者权限字符重复！");
            return result;
        }
        //删除关联的角色菜单
        sysRoleMenuService.deleteMenuIdsByRoleId(dto.getId());
        List<SysRoleMenu> menus = new ArrayList<>();
        //绑定新的角色菜单
        dto.getMenuIds().forEach(dt ->{
            menus.add(new SysRoleMenu(dto.getId(),dt));
        });
        sysRoleMenuService.saveBatchRoleMenu(menus);
        return updateRoleEntity(result,dto);
    }

    @Override
    @Transactional
    public Response addRole(AddRoleDto dto) {
        Response result = Response.fail();
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SysRole::getName,dto.getName())
                .or()
                .eq(SysRole::getRoleName,dto.getRoleName());
        List<SysRole> list = this.list(queryWrapper);
        if (!list.isEmpty()){
            result.setMsg("名称或者权限字符重复！");
            return result;
        }

        SysRole sysRole = addRoleEntity(dto);
        List<SysRoleMenu> menus = new ArrayList<>();
        //绑定新的角色菜单
        dto.getMenuIds().forEach(dt ->{
            menus.add(new SysRoleMenu(sysRole.getId(),dt));
        });
        sysRoleMenuService.saveBatchRoleMenu(menus);
        return Response.ok();
    }

    @Override
    @Transactional
    public boolean delRole(List<Integer> ids) {
        for (Integer id : ids){
            sysRoleMenuService.deleteMenuIdsByRoleId(id);
        }
        return this.removeByIds(ids);
    }

    @Override
    @Transactional
    public boolean updateStatus(Integer roleId, Integer status) {
        UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(BaseModel::getStatus,status)
                .eq(SysRole::getId,roleId);
        return this.update(updateWrapper);
    }

    @Override
    public List<SelectRoleVo> listRoleNotRemove() {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .ne(BaseModel::getStatus, DataStatusEnum.DEL_STATUS.getValue());
        List<SysRole> list = this.list(queryWrapper);
        List<SelectRoleVo> voList = new ArrayList<>();
        list.forEach(l ->{
            voList.add(new SelectRoleVo(l.getId(),l.getName(), !l.getStatus().equals(DataStatusEnum.NORMAL_STATUS.getValue())));
        });
        return voList;
    }


    public Response updateRoleEntity(Response res,UpdateRoleDto dto){
        //更新角色
        SysRole role = new SysRole();
        role.setId(dto.getId());
        role.setName(dto.getName());
        role.setRemark(dto.getRemark());
        role.setRoleName(dto.getRoleName());
        role.setStatus(Integer.valueOf(dto.getStatus()));
        role.setUpdateTime(LocalDateTime.now());
        boolean result = this.saveOrUpdate(role);
        if (result){
            return Response.ok();
        }
        return res;
    }

    public SysRole addRoleEntity(AddRoleDto addRoleDto){
        //更新角色
        SysRole role = new SysRole();
        role.setName(addRoleDto.getName());
        role.setRemark(addRoleDto.getRemark());
        role.setRoleName(addRoleDto.getRoleName());
        role.setStatus(Integer.valueOf(addRoleDto.getStatus()));
        LocalDateTime now = LocalDateTime.now();
        role.setCreateTime(now);
        role.setUpdateTime(now);
        this.save(role);
        return role;
    }



}
